package no.sachmuld.methodcombination.impl.annotation;

import no.sachmuld.methodcombination.api.Direction;
import no.sachmuld.methodcombination.api.annotation.SimpleMethodCombinationDefaults;
import no.sachmuld.methodcombination.api.reflection.component.SimpleMethodCombination;
import no.sachmuld.methodcombination.api.reflection.component.MethodCombination;

import java.lang.annotation.Annotation;
import java.util.Map;

/**
 *
 */
public abstract class SimpleMethodCombinationInitializer implements MethodCombinationInitializer {

    protected void addSimpleMethodCombinationProperties(SimpleMethodCombination simpleMethodCombination, Class aroundBehaviourClass, String primaryMethodName, Direction direction) {

        if (aroundBehaviourClass != SimpleMethodCombinationDefaults.Null.class) {
            simpleMethodCombination.setAroundBehaviourClass(aroundBehaviourClass);
        }
        if (!SimpleMethodCombinationDefaults.DEFAULT_METHOD.equals(primaryMethodName)) {
            simpleMethodCombination.setPrimaryMethodName(primaryMethodName);
        }
        simpleMethodCombination.setDirection(direction);

    }

    public static class List extends SimpleMethodCombinationInitializer {

        @Override
        public void initialize(MethodCombination methodCombination, Annotation annotation, Map<Class<? extends MethodCombination>, MethodCombination> dependencyMap) {
            SimpleMethodCombination simpleMethodCombination = (SimpleMethodCombination) methodCombination;
            no.sachmuld.methodcombination.api.annotation.List a = (no.sachmuld.methodcombination.api.annotation.List) annotation;
            addSimpleMethodCombinationProperties(simpleMethodCombination, a.aroundBehaviour(), a.primaryMethod(), a.direction());
        }
    }

    public static class Append extends SimpleMethodCombinationInitializer {

        @Override
        public void initialize(MethodCombination methodCombination, Annotation annotation, Map<Class<? extends MethodCombination>, MethodCombination> dependencyMap) {
            SimpleMethodCombination simpleMethodCombination = (SimpleMethodCombination) methodCombination;
            no.sachmuld.methodcombination.api.annotation.Append a = (no.sachmuld.methodcombination.api.annotation.Append) annotation;
            addSimpleMethodCombinationProperties(simpleMethodCombination, a.aroundBehaviour(), a.primaryMethod(), a.direction());
        }
    }

    public static class Or extends SimpleMethodCombinationInitializer {

        @Override
        public void initialize(MethodCombination methodCombination, Annotation annotation, Map<Class<? extends MethodCombination>, MethodCombination> dependencyMap) {
            SimpleMethodCombination simpleMethodCombination = (SimpleMethodCombination) methodCombination;
            no.sachmuld.methodcombination.api.annotation.Or a = (no.sachmuld.methodcombination.api.annotation.Or) annotation;
            addSimpleMethodCombinationProperties(simpleMethodCombination, a.aroundBehaviour(), a.primaryMethod(), a.direction());
        }
    }

    public static class And extends SimpleMethodCombinationInitializer {

        @Override
        public void initialize(MethodCombination methodCombination, Annotation annotation, Map<Class<? extends MethodCombination>, MethodCombination> dependencyMap) {
            SimpleMethodCombination simpleMethodCombination = (SimpleMethodCombination) methodCombination;
            no.sachmuld.methodcombination.api.annotation.And a = (no.sachmuld.methodcombination.api.annotation.And) annotation;
            addSimpleMethodCombinationProperties(simpleMethodCombination, a.aroundBehaviour(), a.primaryMethod(), a.direction());
        }
    }

    public static class All extends SimpleMethodCombinationInitializer {

        @Override
        public void initialize(MethodCombination methodCombination, Annotation annotation, Map<Class<? extends MethodCombination>, MethodCombination> dependencyMap) {
            SimpleMethodCombination simpleMethodCombination = (SimpleMethodCombination) methodCombination;
            no.sachmuld.methodcombination.api.annotation.All a = (no.sachmuld.methodcombination.api.annotation.All) annotation;
            addSimpleMethodCombinationProperties(simpleMethodCombination, a.aroundBehaviour(), a.primaryMethod(), a.direction());
        }
    }

    public static class Sum extends SimpleMethodCombinationInitializer {

        @Override
        public void initialize(MethodCombination methodCombination, Annotation annotation, Map<Class<? extends MethodCombination>, MethodCombination> dependencyMap) {
            SimpleMethodCombination simpleMethodCombination = (SimpleMethodCombination) methodCombination;
            no.sachmuld.methodcombination.api.annotation.Sum a = (no.sachmuld.methodcombination.api.annotation.Sum) annotation;
            addSimpleMethodCombinationProperties(simpleMethodCombination, a.aroundBehaviour(), a.primaryMethod(), a.direction());
        }
    }

    public static class Min extends SimpleMethodCombinationInitializer {

        @Override
        public void initialize(MethodCombination methodCombination, Annotation annotation, Map<Class<? extends MethodCombination>, MethodCombination> dependencyMap) {
            SimpleMethodCombination simpleMethodCombination = (SimpleMethodCombination) methodCombination;
            no.sachmuld.methodcombination.api.annotation.Min a = (no.sachmuld.methodcombination.api.annotation.Min) annotation;
            addSimpleMethodCombinationProperties(simpleMethodCombination, a.aroundBehaviour(), a.primaryMethod(), a.direction());
        }
    }

    public static class Max extends SimpleMethodCombinationInitializer {

        @Override
        public void initialize(MethodCombination methodCombination, Annotation annotation, Map<Class<? extends MethodCombination>, MethodCombination> dependencyMap) {
            SimpleMethodCombination simpleMethodCombination = (SimpleMethodCombination) methodCombination;
            no.sachmuld.methodcombination.api.annotation.Max a = (no.sachmuld.methodcombination.api.annotation.Max) annotation;
            addSimpleMethodCombinationProperties(simpleMethodCombination, a.aroundBehaviour(), a.primaryMethod(), a.direction());
        }
    }

}
